﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Gmantis.Controls.DataGrid
{
    public interface IDataGridFilter
    {
        // Events
        event EventHandler<PropertyChangedEventArgs<DataGridFilterState>> FilterChanged;

        // Methods
        void Clear();
        void Create();
        void Load(DataGridFilterState filterState);
    }

    public interface IDataGridFilterUnity : INotifyPropertyChanged
    {
        // Properties
        DataGridFilterState Filter { get; set; }
    }

    public enum DataGridOptionsVisibility
    {
        Visible,
        OnMouseOver
    }

    public enum DataGridSortDirection
    {
        None,
        Ascending,
        Descending
    }

    public enum DataGridColumnHeaderClickAction
    {
        Sort,
        Select
    }

    [TemplateVisualState(Name = "NotMerging", GroupName = "MergingStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), 
    TemplatePart(Name = "Resize", Type = typeof(FrameworkElement)), 
    TemplatePart(Name = "Sort", Type = typeof(ToggleButton)), 
    TemplatePart(Name = "Options", Type = typeof(DropDown)), 
    TemplatePart(Name = "Remove", Type = typeof(Button)), 
    TemplateVisualState(Name = "Undefined", GroupName = "OptionsStates"), 
    TemplateVisualState(Name = "Filtering", GroupName = "OptionsStates"), 
    TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Editing", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Merging", GroupName = "MergingStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
    public class DataGridColumnHeaderPresenter : ContentControl, IRecyclable, INotifyPropertyChanged
    {
        // Fields
        private double _actualWidth;
        internal DropDown _elementOptions;
        internal Button _elementRemove;
        internal FrameworkElement _elementResize;
        internal ToggleButton _elementSort;
        private IDataGridFilter _filterControl;
        private TapHelper _headerMouseHelper;
        internal bool _isLoaded;
        private DragHelper _resizeDragHelper;
        private TapHelper _resizeMouseHelper;
        private bool _throwIsMouseOverChanged;
        private ViewColumn _viewColumn;
        internal static readonly DependencyProperty CanUserFilterProperty = DependencyProperty.Register("CanUserFilter", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(true, new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnCanUserFilterPropertyChanged)));
        internal static readonly DependencyProperty CanUserResizeProperty = DependencyProperty.Register("CanUserResize", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(true, new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnCanUserResizePropertyChanged)));
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnForceMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsEditingProperty = DependencyProperty.Register("IsEditing", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnIsEditingPropertyChanged)));
        public static readonly DependencyProperty IsFilteringProperty = DependencyProperty.Register("IsFiltering", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnIsFilteringPropertyChanged)));
        public static readonly DependencyProperty IsInGroupingPanelProperty = DependencyProperty.Register("IsInGroupingPanel", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(false));
        public static readonly DependencyProperty IsMergingProperty = DependencyProperty.Register("IsMerging", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnIsMergingPropertyChanged)));
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnIsMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnIsSelectedPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(DataGridColumnHeaderPresenter), null);
        internal const string OptionsElementName = "Options";
        public static readonly DependencyProperty OptionsVisibilityProperty = DependencyProperty.Register("OptionsVisibility", typeof(DataGridOptionsVisibility), typeof(DataGridColumnHeaderPresenter), new PropertyMetadata(DataGridOptionsVisibility.OnMouseOver, new PropertyChangedCallback(DataGridColumnHeaderPresenter.OnOptionsVisibilityPropertyChanged)));
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(DataGridColumnHeaderPresenter), null);
        internal const string RemoveElementName = "Remove";
        internal const string ResizeElementName = "Resize";
        public static readonly DependencyProperty SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(DataGridColumnHeaderPresenter), null);
        internal const string SortElementName = "Sort";

        // Events
        public event EventHandler AutoSized;
        public event EventHandler<PropertyChangedEventArgs<DataGridFilterState>> FilterChanged;
        public event EventHandler<DataGridColumnEditableValueEventArgs<IDataGridFilter>> FilterLoading;
        public event EventHandler<DataGridColumnValueEventArgs<IDataGridFilter>> FilterOpened;
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;
        public event PropertyChangedEventHandler PropertyChanged;
        public event EventHandler<PropertyChangedEventArgs<double>> Resized;
        public event EventHandler<PropertyChangedEventArgs<double>> Resizing;

        // Methods
        public DataGridColumnHeaderPresenter()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(DataGridColumnHeaderPresenter);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateOptions(false);
                    this.ChangeVisualStateSelection(false);
                    this.ChangeVisualStateMerging(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            this.SetCustomDefaultValues();
        }

        private void _elementOptions_IsDropDownOpenChanged(object sender, PropertyChangedEventArgs<bool> e)
        {
            Action a = null;
            this.UpdateOptionsVisibility(false);
            if (e.NewValue)
            {
                this.UpdateFilter();
                if (a == null)
                {
                    a = delegate
                    {
                        if (this.Filter is DependencyObject)
                        {
                            this.SetFocus(this.Filter as DependencyObject);
                        }
                    };
                }
                base.Dispatcher.BeginInvoke(a);
                this.OnFilterOpened(this, new DataGridColumnValueEventArgs<IDataGridFilter>(this.Column, this._elementOptions.Content as IDataGridFilter));
            }
        }

        private void _filter_FilterChanged(object sender, PropertyChangedEventArgs<DataGridFilterState> e)
        {
            if (this.FilterChanged != null)
            {
                this.FilterChanged(sender, e);
            }
            this._elementOptions.IsDropDownOpen = false;
            if (this.DataGrid != null)
            {
                this.DataGrid.Focus();
            }
            this.UpdateOptionsVisibility(false);
        }

        private void AddFilterToDropDown()
        {
            if (this._elementOptions != null)
            {
                this._elementOptions.Content = this.Filter;
                if (this.Filter is FrameworkElement)
                {
                    (this.Filter as FrameworkElement).KeyDown += new KeyEventHandler(this.Filter_KeyDown);
                }
            }
        }

        void IRecyclable.Collect()
        {
            this.IsCollected = true;
            if (this.ViewColumn != null)
            {
                this.ViewColumn.FinalizeColumnHeaderPresenter();
            }
        }

        object IRecyclable.GetRecyclingKey()
        {
            if (this.ViewColumn == null)
            {
                return null;
            }
            return this.ViewColumn.GetColumnHeaderPresenterRecyclingKey();
        }

        void IRecyclable.Reuse()
        {
            this.IsCollected = false;
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateMerging(bool useTransitions)
        {
            if (!this.IsMerging)
            {
                VisualStateHelper.GoToState(this, "NotMerging", useTransitions);
            }
            if (this.IsMerging)
            {
                VisualStateHelper.GoToState(this, "Merging", useTransitions);
            }
        }

        protected void ChangeVisualStateOptions(bool useTransitions)
        {
            if (this.IsFiltering)
            {
                VisualStateHelper.GoToState(this, "Filtering", useTransitions);
            }
            if (!this.IsFiltering)
            {
                VisualStateHelper.GoToState(this, "Undefined", useTransitions);
            }
        }

        protected void ChangeVisualStateSelection(bool useTransitions)
        {
            if (this.IsSelected && this.IsEditing)
            {
                VisualStateHelper.GoToState(this, "Editing", useTransitions);
            }
            if (this.IsSelected && !this.IsEditing)
            {
                VisualStateHelper.GoToState(this, "Selected", useTransitions);
            }
            if (!this.IsSelected)
            {
                VisualStateHelper.GoToState(this, "Unselected", useTransitions);
            }
        }

        private void DataGridColumnHeader_MouseEnter(object sender, MouseEventArgs e)
        {
            this.UpdateOptionsVisibility(true);
            this.UpdateIsEnabledOptions();
        }

        private void DataGridColumnHeader_MouseLeave(object sender, MouseEventArgs e)
        {
            this.UpdateOptionsVisibility(false);
        }

        private void Filter_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                this._elementOptions.IsDropDownOpen = false;
                this.DataGrid.Focus();
                e.Handled = true;
            }
            if (e.Key == Key.Enter)
            {
                this.Filter.Create();
                e.Handled = true;
            }
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private void InitializeOptionsPart()
        {
            this.UpdateOptionsVisibility(false);
            TapHelper helper = new TapHelper(this._elementOptions, false);
            helper.Tapped += (s, e) => e.Handled = true;
            this._elementOptions.AutoClose = true;
            this.AddFilterToDropDown();
            this._elementOptions.IsDropDownOpenChanged += new EventHandler<PropertyChangedEventArgs<bool>>(this._elementOptions_IsDropDownOpenChanged);
            this.UpdateFilterStyle();
            this.UpdateIsEnabledOptions();
        }

        private void InitializeRemovePart()
        {
            this._elementRemove.Click += delegate(object s, RoutedEventArgs e)
            {
                try
                {
                    if (this.ViewColumn != null)
                    {
                        this.ViewColumn.View.Model.RemoveGroup(this.ViewColumn.Column);
                    }
                }
                catch (DataGridGroupException)
                {
                }
            };
        }

        private void InitializeResizePart()
        {
            this._resizeMouseHelper = new TapHelper(this._elementResize, false);
            this._resizeDragHelper = new DragHelper(this._elementResize, DragHelperMode.TranslateXY, 1.0, true, false, false, false);
            this._resizeMouseHelper.DoubleTapped += new EventHandler<TappedEventArgs>(this.OnResizeMouseDoubleTapped);
            this._resizeDragHelper.DragStarted += new EventHandler<DragStartedEventArgs>(this.OnResizeDragStarted);
            this._resizeDragHelper.DragDelta += new EventHandler<DragDeltaEventArgs>(this.OnResizeDragDelta);
            this._resizeDragHelper.DragCompleted += new EventHandler<DragCompletedEventArgs>(this.OnResizeDragCompleted);
            this.UpdateResizeVisibility();
        }

        private void InitializeSortPart()
        {
            this._elementSort.IsHitTestVisible = false;
            this._elementSort.IsThreeState = true;
            this.UpdateSort();
        }

        protected internal virtual void Load()
        {
            this.UpdateSelection();
            this.UpdateSort();
        }

        public override void OnApplyTemplate()
        {
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementResize = this.GetTemplateChild<FrameworkElement>("Resize", false, ref errors);
            if (this._elementResize != null)
            {
                this.InitializeResizePart();
            }
            this._elementSort = this.GetTemplateChild<ToggleButton>("Sort", false, ref errors);
            if (this._elementSort != null)
            {
                this.InitializeSortPart();
            }
            this._elementOptions = this.GetTemplateChild<DropDown>("Options", false, ref errors);
            if (this._elementOptions != null)
            {
                this.InitializeOptionsPart();
            }
            this._elementRemove = this.GetTemplateChild<Button>("Remove", false, ref errors);
            if (this._elementRemove != null)
            {
                this.InitializeRemovePart();
            }
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to DataGridColumnHeaderPresenter.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateOptions(false);
                this.ChangeVisualStateSelection(false);
                this.ChangeVisualStateMerging(false);
                this.ChangeVisualStateCommon(false);
            }
        }

        private static void OnCanUserFilterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridColumnHeaderPresenter presenter = d as DataGridColumnHeaderPresenter;
            presenter.UpdateIsEnabledOptions();
            presenter.UpdateOptionsVisibility(false);
        }

        private static void OnCanUserResizePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridColumnHeaderPresenter).UpdateResizeVisibility();
        }

        private void OnFilterLoading(object sender, DataGridColumnEditableValueEventArgs<IDataGridFilter> e)
        {
            if (this.FilterLoading != null)
            {
                this.FilterLoading(sender, e);
            }
        }

        private void OnFilterOpened(object sender, DataGridColumnValueEventArgs<IDataGridFilter> e)
        {
            if (this.FilterOpened != null)
            {
                this.FilterOpened(sender, e);
            }
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridColumnHeaderPresenter).ChangeVisualStateCommon(true);
        }

        private static void OnIsEditingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridColumnHeaderPresenter).ChangeVisualStateSelection(true);
        }

        private void OnIsFilteringChanged(bool oldValue)
        {
            this.UpdateOptionsVisibility(false);
        }

        private static void OnIsFilteringPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridColumnHeaderPresenter presenter = d as DataGridColumnHeaderPresenter;
            bool oldValue = (bool)e.OldValue;
            presenter.OnIsFilteringChanged(oldValue);
            presenter.ChangeVisualStateOptions(true);
        }

        private static void OnIsMergingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridColumnHeaderPresenter).ChangeVisualStateMerging(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridColumnHeaderPresenter sender = d as DataGridColumnHeaderPresenter;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private static void OnIsSelectedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGridColumnHeaderPresenter).ChangeVisualStateSelection(true);
        }

        protected override void OnMouseEnter(MouseEventArgs e)
        {
            if (this.View != null)
            {
                this.View.SetMouseOverColumn(this.Column);
            }
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            if (this.View != null)
            {
                this.View.ClearMouseOver();
            }
        }

        private void OnOptionsVisibilityChanged(DataGridOptionsVisibility oldValue)
        {
            this.UpdateOptionsVisibility(true);
        }

        private static void OnOptionsVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGridColumnHeaderPresenter presenter = d as DataGridColumnHeaderPresenter;
            DataGridOptionsVisibility oldValue = (DataGridOptionsVisibility)e.OldValue;
            presenter.OnOptionsVisibilityChanged(oldValue);
        }

        private void OnResizeDragCompleted(object sender, DragCompletedEventArgs e)
        {
            if (this.Resized != null)
            {
                double num = this._actualWidth + e.CumulativeTranslation.X;
                PropertyChangedEventArgs<double> args = new PropertyChangedEventArgs<double>
                {
                    OldValue = base.ActualWidth,
                    NewValue = (num >= 0.0) ? num : 0.0
                };
                this.Resized(this, args);
            }
        }

        private void OnResizeDragDelta(object sender, DragDeltaEventArgs e)
        {
            if (this.Resizing != null)
            {
                double num = this._actualWidth + e.CumulativeTranslation.X;
                PropertyChangedEventArgs<double> args = new PropertyChangedEventArgs<double>
                {
                    OldValue = base.ActualWidth,
                    NewValue = (num >= 0.0) ? num : 0.0
                };
                this.Resizing(this, args);
            }
        }

        private void OnResizeDragStarted(object sender, DragStartedEventArgs e)
        {
            if (this.Column != null)
            {
                this._actualWidth = this.Column.ActualWidth;
            }
            else
            {
                this._actualWidth = base.ActualWidth;
            }
        }

        private void OnResizeMouseDoubleTapped(object sender, TappedEventArgs e)
        {
            if (this.AutoSized != null)
            {
                this.AutoSized(this, new EventArgs());
                e.Handled = true;
            }
        }

        private void OnTapped(object sender, TappedEventArgs e)
        {
            if (this.DataGrid != null)
            {
                try
                {
                    if (this.IsInGroupingPanel)
                    {
                        if (this.DataGrid.CanUserGroup)
                        {
                            DataGridSortDirection direction = this.Column.GroupState.Direction;
                            try
                            {
                                this.DataGrid.GroupBy(this.Column, (direction == DataGridSortDirection.Ascending) ? DataGridSortDirection.Descending : DataGridSortDirection.Ascending, true);
                            }
                            catch (DataGridGroupException)
                            {
                            }
                        }
                    }
                    else if (e.OriginalSource != this._elementResize)
                    {
                        DataGridSortDirection direction2 = this.Column.SortState.Direction;
                        if (this.DataGrid.ColumnHeaderClickAction == DataGridColumnHeaderClickAction.Sort)
                        {
                            if (this.Column.ActualCanUserSort && this.IsSingleton)
                            {
                                try
                                {
                                    this.DataGrid.SortBy(this.Column, (direction2 == DataGridSortDirection.Ascending) ? DataGridSortDirection.Descending : DataGridSortDirection.Ascending, KeyboardUtil.Ctrl);
                                }
                                catch (DataGridSortException)
                                {
                                }
                            }
                        }
                        else
                        {
                            try
                            {
                                if (this.DataGrid.Model.SetCurrentColumn(this.Column, false))
                                {
                                    this.DataGrid.Model.SelectionManager.Select(this.Column);
                                }
                            }
                            catch
                            {
                            }
                        }
                    }
                }
                catch (DataGridFinalizeEditingException)
                {
                }
            }
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void SetCustomDefaultValues()
        {
            base.IsTabStop = false;
            this._headerMouseHelper = new TapHelper(this, false);
            this._headerMouseHelper.Tapped += new EventHandler<TappedEventArgs>(this.OnTapped);
            base.MouseEnter += new MouseEventHandler(this.DataGridColumnHeader_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.DataGridColumnHeader_MouseLeave);
        }

        private bool SetFocus(DependencyObject o)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(o, i);
                if (((child is Control) && ((Control)child).IsTabStop) && ((Control)child).Focus())
                {
                    return true;
                }
                if (this.SetFocus(child))
                {
                    return true;
                }
            }
            return false;
        }

        protected internal virtual void Unload()
        {
            this.UnloadFilter();
            this.UnloadSort();
        }

        private void UnloadFilter()
        {
            FrameworkElement filter = this.Filter as FrameworkElement;
            if ((filter != null) && (filter.Parent is ContentControl))
            {
                (filter.Parent as ContentControl).Content = null;
                filter.KeyDown -= new KeyEventHandler(this.Filter_KeyDown);
            }
            this.Filter = null;
        }

        private void UnloadSort()
        {
            if (this._elementSort != null)
            {
                this._elementSort.ClearValue(ToggleButton.IsCheckedProperty);
                this._elementSort.ClearValue(UIElement.VisibilityProperty);
            }
        }

        private void UpdateFilter()
        {
            if (this.Filter == null)
            {
                IDataGridFilter filter = this.Column.Filter;
                DataGridColumnEditableValueEventArgs<IDataGridFilter> e = new DataGridColumnEditableValueEventArgs<IDataGridFilter>(this.Column, filter);
                this.OnFilterLoading(this, e);
                this.Filter = e.Value;
                this.UpdateFilterStyle();
                this.AddFilterToDropDown();
            }
            if (this.Filter != null)
            {
                this.Filter.Load(this.Column.FilterState);
            }
        }

        private void UpdateFilterStyle()
        {
            DataGridFilter target = this.Filter as DataGridFilter;
            if (target != null)
            {
                if ((this.DataGrid != null) && (this.DataGrid.FilterStyle != target.Style))
                {
                    target.Style = this.DataGrid.FilterStyle;
                }
                target.SetBinding<DataGrid>(Control.BackgroundProperty, this.DataGrid, dg => dg.HeaderBackground);
                target.SetBinding<DataGrid>(Control.ForegroundProperty, this.DataGrid, dg => dg.HeaderForeground);
                target.SetBinding<DataGrid>(Control.BorderBrushProperty, this.DataGrid, dg => dg.BorderBrush);
                target.SetBinding<DataGrid>(Control.BorderThicknessProperty, this.DataGrid, dg => dg.BorderThickness);
                target.SetBinding<DataGrid>(DataGridFilter.MouseOverBrushProperty, this.DataGrid, dg => dg.MouseOverBrush);
                target.SetBinding<DataGrid>(DataGridFilter.PressedBrushProperty, this.DataGrid, dg => dg.PressedBrush);
                target.SetBinding<DataGrid>(DataGridFilter.FocusBrushProperty, this.DataGrid, dg => dg.SelectedBackground);
            }
        }

        private void UpdateIsEnabledOptions()
        {
            if ((this._elementOptions != null) && (this.Column != null))
            {
                this._elementOptions.IsEnabled = this.Column.ActualCanUserFilter;
            }
        }

        internal void UpdateMouseOver()
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                this.ForceMouseOver = this.Column.IsMouseOver;
            }
        }

        internal void UpdateOptionsVisibility(bool showFilter)
        {
            if ((this._elementOptions != null) && (this.Column != null))
            {
                Visibility collapsed;
                if (!this.IsSingleton)
                {
                    collapsed = Visibility.Collapsed;
                }
                else if (this.Column.ActualCanUserFilter && ((this.OptionsVisibility == DataGridOptionsVisibility.Visible) || showFilter))
                {
                    collapsed = Visibility.Visible;
                }
                else if (this._elementOptions.IsDropDownOpen)
                {
                    collapsed = Visibility.Visible;
                }
                else if (this.Column.FilterState != null)
                {
                    collapsed = Visibility.Visible;
                }
                else
                {
                    collapsed = Visibility.Collapsed;
                }
                this._elementOptions.Visibility = collapsed;
            }
        }

        private void UpdateResizeVisibility()
        {
            if (this._elementResize != null)
            {
                this._elementResize.Visibility = (this.CanUserResize && !this.IsInGroupingPanel) ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        internal void UpdateSelection()
        {
            if (!DesignerProperties.GetIsInDesignMode(this))
            {
                this.IsSelected = !this.ViewColumn.View.Model.SelectionManager.Selection.Mode.IsRowSelectionMode() && this.Column.IsSelected;
            }
        }

        private void UpdateSort()
        {
            if (this._elementSort != null)
            {
                if (this.Column != null)
                {
                    Binding binding2 = new Binding(this.IsInGroupingPanel ? "GroupState.Direction" : "SortState.Direction")
                    {
                        Source = this.Column,
                        Mode = BindingMode.OneWay,
                        Converter = CustomConverter.Create(delegate(object value, Type type, object parameter, CultureInfo culture)
                        {
                            switch ((DataGridSortDirection)value)
                            {
                                case DataGridSortDirection.Ascending:
                                    return false;

                                case DataGridSortDirection.Descending:
                                    return true;
                            }
                            return null;
                        })
                    };
                    this._elementSort.SetBinding(ToggleButton.IsCheckedProperty, binding2);
                    if (base.Parent is DataGridCellPresenter)
                    {
                        DataGridCellPresenter parent = (DataGridCellPresenter)base.Parent;
                        parent.MergedRange.GetType();
                        Binding binding = new Binding
                        {
                            Converter = CustomConverter.Create(delegate(object value, Type type, object parameter, CultureInfo culture)
                            {
                                DataGridCellsRange range = (DataGridCellsRange)value;
                                if (range.TopLeftCell.Column == range.BottomRightCell.Column)
                                {
                                    return Visibility.Visible;
                                }
                                return Visibility.Collapsed;
                            })
                        };
                        this._elementSort.SetBinding(UIElement.VisibilityProperty, binding.From<DataGridCellPresenter>(parent, x => x.MergedRange));
                    }
                }
                else
                {
                    this._elementSort.IsChecked = null;
                }
            }
        }

        // Properties
        bool IRecyclable.IsCollected
        {
            get
            {
                return this.IsCollected;
            }
        }

        private bool CanUserFilter
        {
            get
            {
                return (bool)base.GetValue(CanUserFilterProperty);
            }
        }

        private bool CanUserResize
        {
            get
            {
                return (bool)base.GetValue(CanUserResizeProperty);
            }
        }

        public DataGridColumn Column
        {
            get
            {
                if (this.ViewColumn != null)
                {
                    return this.ViewColumn.Column;
                }
                return null;
            }
        }

        public DataGrid DataGrid
        {
            get
            {
                if (this.ViewColumn != null)
                {
                    return this.Column.DataGrid;
                }
                return null;
            }
        }

        public IDataGridFilter Filter
        {
            get
            {
                return this._filterControl;
            }
            set
            {
                if (this._filterControl != null)
                {
                    this._filterControl.FilterChanged -= new EventHandler<PropertyChangedEventArgs<DataGridFilterState>>(this._filter_FilterChanged);
                }
                this._filterControl = value;
                if (this._filterControl != null)
                {
                    this.UpdateFilterStyle();
                    this._filterControl.FilterChanged += new EventHandler<PropertyChangedEventArgs<DataGridFilterState>>(this._filter_FilterChanged);
                }
                if (this._elementOptions != null)
                {
                    this._elementOptions.Content = this._filterControl;
                }
            }
        }

        internal bool ForceMouseOver
        {
            get
            {
                return (bool)base.GetValue(ForceMouseOverProperty);
            }
            set
            {
                base.SetValue(ForceMouseOverProperty, value);
            }
        }

        internal bool IsCollected { get; private set; }

        public bool IsEditing
        {
            get
            {
                return (bool)base.GetValue(IsEditingProperty);
            }
            set
            {
                base.SetValue(IsEditingProperty, value);
            }
        }

        public bool IsFiltering
        {
            get
            {
                return (bool)base.GetValue(IsFilteringProperty);
            }
            set
            {
                base.SetValue(IsFilteringProperty, value);
            }
        }

        public bool IsInGroupingPanel
        {
            get
            {
                return (bool)base.GetValue(IsInGroupingPanelProperty);
            }
            set
            {
                base.SetValue(IsInGroupingPanelProperty, value);
            }
        }

        public bool IsMerging
        {
            get
            {
                return (bool)base.GetValue(IsMergingProperty);
            }
            set
            {
                base.SetValue(IsMergingProperty, value);
            }
        }

        public bool IsMouseOver
        {
            get
            {
                return (bool)base.GetValue(IsMouseOverProperty);
            }
            internal set
            {
                base.SetValue(IsMouseOverProperty, value);
            }
        }

        public bool IsSelected
        {
            get
            {
                return (bool)base.GetValue(IsSelectedProperty);
            }
            set
            {
                base.SetValue(IsSelectedProperty, value);
            }
        }

        internal bool IsSingleton
        {
            get
            {
                if (!(base.Parent is DataGridCellPresenter))
                {
                    return true;
                }
                DataGridCellPresenter parent = (DataGridCellPresenter)base.Parent;
                DataGridCellsRange mergedRange = parent.MergedRange;
                return (mergedRange.TopLeftCell.Column == mergedRange.BottomRightCell.Column);
            }
        }

        public Brush MouseOverBrush
        {
            get
            {
                return (Brush)base.GetValue(MouseOverBrushProperty);
            }
            set
            {
                base.SetValue(MouseOverBrushProperty, value);
            }
        }

        public DataGridOptionsVisibility OptionsVisibility
        {
            get
            {
                return (DataGridOptionsVisibility)base.GetValue(OptionsVisibilityProperty);
            }
            set
            {
                base.SetValue(OptionsVisibilityProperty, value);
            }
        }

        public Brush PressedBrush
        {
            get
            {
                return (Brush)base.GetValue(PressedBrushProperty);
            }
            set
            {
                base.SetValue(PressedBrushProperty, value);
            }
        }

        public Brush SelectedBackground
        {
            get
            {
                return (Brush)base.GetValue(SelectedBackgroundProperty);
            }
            set
            {
                base.SetValue(SelectedBackgroundProperty, value);
            }
        }

        internal DataGridView View
        {
            get
            {
                if (this.ViewColumn == null)
                {
                    return null;
                }
                return this.ViewColumn.View;
            }
        }

        internal ViewColumn ViewColumn
        {
            get
            {
                return this._viewColumn;
            }
            set
            {
                if (this._viewColumn != value)
                {
                    this._viewColumn = value;
                    this.RaisePropertyChanged("Column");
                }
            }
        }
    }

    public class DataGridGroupColumnHeaderPresenter : DataGridColumnHeaderPresenter
    {
        public DataGridGroupColumnHeaderPresenter()
        {
            base.DefaultStyleKey = typeof(DataGridGroupColumnHeaderPresenter);
        }
    }
}
